package com.ddxz.common.route.filter;

import com.ddxz.common.route.service.GatewayService;
import com.ddxz.tool.core.common.DdxzJwtUtil;
import com.ddxz.tool.core.convert.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UrlPathHelper;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * class description
 *
 * @author 朱宗刚
 * @version 1.0.0
 * @date 2020/8/18
 */

@Component
public class DdxzFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String url = exchange.getRequest().getURI().getPath();
        logger.debug("=========={}==========", url);
        AntPathMatcher pathMatcher = new AntPathMatcher();
        for (String pat : ANON_URL) {
            if (pathMatcher.match(pat, url)) {
                return chain.filter(exchange);
            }
        }

        try {
            String token = exchange.getRequest().getHeaders().getFirst("Authorization");
            Map<String, Object> headers = jwtUtil.getBody(token);
            if(!service.isPermission(headers.get("roleIds").toString(), url)) {
                exchange.getResponse().setStatusCode( HttpStatus.UNAUTHORIZED );
                return exchange.getResponse().setComplete();
            }
            ServerHttpRequest.Builder request = exchange.getRequest().mutate();
            headers.forEach((key, val) -> request.header(key, val.toString()));
            exchange.getResponse().getHeaders().add("Authorization", jwtUtil.getToken(headers, expired));
            return chain.filter(exchange.mutate().request(request.build()).build());
        } catch (Exception e) {
            e.printStackTrace();
            exchange.getResponse().setStatusCode( HttpStatus.UNAUTHORIZED );
            return exchange.getResponse().setComplete();
        }
    }

    private DdxzJwtUtil jwtUtil = new DdxzJwtUtil();
    private static final Logger logger = LoggerFactory.getLogger(DdxzFilter.class);

    @Autowired
    private GatewayService service;

    @Override
    public int getOrder() {
        return 0;
    }

    private UrlPathHelper urlPathHelper = new UrlPathHelper();
    private static final List<String> ANON_URL = new ArrayList<>();

    private Long expired;

    @Value("${ddxz.token.expired}")
    public void setExpired(String expired) {
        this.expired = StringUtil.toLong(expired);
    }

    static {
        ANON_URL.add("/swagger-ui.html");
        ANON_URL.add("/webjars/springfox-swagger-ui/**");
        ANON_URL.add("/swagger-resources/**");
        ANON_URL.add("/v2/api-docs");
        ANON_URL.add("/ddxzmaster/login");
    }
}
